package com.example.sftpclient

import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.OpenableColumns
import android.provider.Settings
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import android.media.MediaScannerConnection
import android.os.Environment
import android.content.pm.PackageManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.View

class MainActivity : AppCompatActivity() {
    private val sftpClient = SftpClient()
    private lateinit var statusText: TextView
    private lateinit var adapter: RemoteFileAdapter
    private lateinit var uploadButton: Button
    private lateinit var downloadButton: Button
    private lateinit var connectButton: Button
    private lateinit var disconnectButton: Button

    
    companion object {
        private const val PICK_FILE_REQUEST_CODE = 1001
        private const val STORAGE_PERMISSION_CODE = 1000
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 检查并请求存储权限
        checkAndRequestStoragePermission()

        val hostInput = findViewById<EditText>(R.id.hostInput)
        val portInput = findViewById<EditText>(R.id.portInput)
        val usernameInput = findViewById<EditText>(R.id.usernameInput)
        val passwordInput = findViewById<EditText>(R.id.passwordInput)
        connectButton = findViewById(R.id.connectButton)
        disconnectButton = findViewById(R.id.disconnectButton)
        statusText = findViewById(R.id.statusText)

        uploadButton = findViewById(R.id.uploadButton)
        downloadButton = findViewById(R.id.downloadButton)
        
        // 初始时隐藏按钮
        disconnectButton.visibility = View.GONE
        uploadButton.visibility = View.GONE
        downloadButton.visibility = View.GONE

        connectButton.setOnClickListener {
            val host = hostInput.text.toString()
            val port = portInput.text.toString().toInt()
            val username = usernameInput.text.toString()
            val password = passwordInput.text.toString()

            CoroutineScope(Dispatchers.IO).launch {
                try {
                    sftpClient.connect(host, username, password, port)
                    withContext(Dispatchers.Main) {
                        // 连接成功后更新按钮状态
                        connectButton.visibility = View.GONE
                        disconnectButton.visibility = View.VISIBLE
                        uploadButton.visibility = View.VISIBLE
                        downloadButton.visibility = View.VISIBLE
                        updateStatus("连接成功！")
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    updateStatus("连接失败：${e.stackTraceToString()}")
                }
            }
        }

        disconnectButton.setOnClickListener {
            CoroutineScope(Dispatchers.IO).launch {
                try {
                    sftpClient.disconnect()
                    withContext(Dispatchers.Main) {
                        // 断开连接后更新按钮状态
                        connectButton.visibility = View.VISIBLE
                        disconnectButton.visibility = View.GONE
                        uploadButton.visibility = View.GONE
                        downloadButton.visibility = View.GONE
                        updateStatus("已断开连接")
                    }
                } catch (e: Exception) {
                    updateStatus("断开连接失败：${e.message}")
                }
            }
        }

        uploadButton.setOnClickListener {
            openFilePicker()
        }

        downloadButton.setOnClickListener {
            showFileBrowser()
        }
    }

    private fun checkAndRequestStoragePermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11及以上版本
            if (!Environment.isExternalStorageManager()) {
                val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
                startActivity(intent)
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // Android 6.0到Android 10
            if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(
                    arrayOf(
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                    ),
                    STORAGE_PERMISSION_CODE
                )
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == STORAGE_PERMISSION_CODE) {
            if (grantResults.isNotEmpty() && 
                grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "存储权限已授予", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this, "需要存储权限才能下载文件", Toast.LENGTH_LONG).show()
            }
        }
    }

    private fun openFilePicker() {
        val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
            type = "*/*"
            addCategory(Intent.CATEGORY_OPENABLE)
        }
        startActivityForResult(intent, PICK_FILE_REQUEST_CODE)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_FILE_REQUEST_CODE && resultCode == RESULT_OK) {
            data?.data?.let { uri ->
                uploadFile(uri)
            }
        }
    }

    private fun uploadFile(uri: Uri) {
        val fileName = getFileName(uri)
        CoroutineScope(Dispatchers.IO).launch {
            try {
                updateStatus("开始上传文件：$fileName")
                
                // 将URI转换为文件路径
                val inputStream = contentResolver.openInputStream(uri)
                val tempFile = File(cacheDir, fileName)
                inputStream?.use { input ->
                    tempFile.outputStream().use { output ->
                        input.copyTo(output)
                    }
                }

                // 上传文件
                sftpClient.uploadFile(tempFile.absolutePath, "/upload/$fileName")
                
                // 删除临时文件
                tempFile.delete()
                
                updateStatus("文件上传成功！")
            } catch (e: Exception) {
                updateStatus("文件上传失败：${e.message}")
            }
        }
    }

    private fun getFileName(uri: Uri): String {
        var fileName = "unknown"
        contentResolver.query(uri, null, null, null, null)?.use { cursor ->
            val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
            cursor.moveToFirst()
            fileName = cursor.getString(nameIndex)
        }
        return fileName
    }

    private fun showFileBrowser() {
        val dialog = AlertDialog.Builder(this)
            .setTitle("远程文件浏览")
            .create()

        val dialogView = layoutInflater.inflate(R.layout.dialog_file_browser, null)
        dialog.setView(dialogView)

        val currentPathText = dialogView.findViewById<TextView>(R.id.currentPathText)
        val parentDirButton = dialogView.findViewById<Button>(R.id.parentDirButton)
        val fileList = dialogView.findViewById<RecyclerView>(R.id.fileList)

        var currentPath = "/"
        
        adapter = RemoteFileAdapter(
            files = emptyList(),
            onItemClick = { file ->
                if (file.isDirectory) {
                    currentPath = file.path
                    loadFiles(currentPath, adapter, currentPathText)
                } else {
                    dialog.dismiss()
                    downloadFile(file.path)
                }
            },
            onItemLongClick = { file ->
                showFileOperationDialog(file)
                true
            }
        )

        fileList.layoutManager = LinearLayoutManager(this)
        fileList.adapter = adapter

        currentPathText.text = currentPath
        loadFiles(currentPath, adapter, currentPathText)

        parentDirButton.setOnClickListener {
            if (currentPath != "/") {
                currentPath = currentPath.substringBeforeLast("/", "/")
                loadFiles(currentPath, adapter, currentPathText)
            }
        }

        dialog.show()
    }

    private fun loadFiles(path: String, adapter: RemoteFileAdapter, pathText: TextView) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val files = sftpClient.listFiles(path)
                withContext(Dispatchers.Main) {
                    adapter.updateFiles(files)
                    pathText.text = path
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@MainActivity, "加载文件列表失败：${e.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun showFileOperationDialog(file: RemoteFile) {
        val operations = arrayOf("删除", if (file.isDirectory) "新建文件夹" else "下载")
        AlertDialog.Builder(this)
            .setTitle(file.name)
            .setItems(operations) { _, which ->
                when (which) {
                    0 -> deleteRemoteFile(file)
                    1 -> if (file.isDirectory) {
                        showCreateDirectoryDialog(file.path)
                    } else {
                        downloadFile(file.path)
                    }
                }
            }
            .show()
    }

    private fun deleteRemoteFile(file: RemoteFile) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                if (file.isDirectory) {
                    sftpClient.deleteDirectory(file.path)
                } else {
                    sftpClient.deleteFile(file.path)
                }
                updateStatus("删除成功：${file.name}")
            } catch (e: Exception) {
                updateStatus("删除失败：${e.message}")
            }
        }
    }

    private fun showCreateDirectoryDialog(parentPath: String) {
        val input = EditText(this)
        AlertDialog.Builder(this)
            .setTitle("新建文件夹")
            .setView(input)
            .setPositiveButton("确定") { _, _ ->
                val dirName = input.text.toString()
                if (dirName.isNotEmpty()) {
                    createRemoteDirectory("$parentPath/$dirName")
                }
            }
            .setNegativeButton("取消", null)
            .show()
    }

    private fun createRemoteDirectory(path: String) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                sftpClient.createDirectory(path)
                updateStatus("创建目录成功")
            } catch (e: Exception) {
                updateStatus("创建目录失败：${e.message}")
            }
        }
    }

    private fun downloadFile(remotePath: String) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                if (!checkStoragePermission()) {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@MainActivity, 
                            "请先授予存储权限", Toast.LENGTH_LONG).show()
                        checkAndRequestStoragePermission()
                    }
                    return@launch
                }

                updateStatus("开始下载文件：$remotePath")
                
                val fileName = remotePath.substringAfterLast("/")
                val downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                val localFile = File(downloadDir, fileName)

                sftpClient.downloadFile(remotePath, localFile.absolutePath)
                
                withContext(Dispatchers.Main) {
                    updateStatus("文件已下载到：${localFile.absolutePath}")
                    // 通知系统图库更新
                    MediaScannerConnection.scanFile(
                        this@MainActivity,
                        arrayOf(localFile.absolutePath),
                        null
                    ) { _, uri ->
                        uri?.let {
                            val intent = Intent(Intent.ACTION_VIEW)
                            intent.setDataAndType(uri, getMimeType(fileName))
                            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                            try {
                                startActivity(intent)
                            } catch (e: Exception) {
                                Toast.makeText(this@MainActivity, "无法打开此类型的文件", Toast.LENGTH_SHORT).show()
                            }
                        }
                    }
                }
            } catch (e: Exception) {
                updateStatus("文件下载失败：${e.message}")
            }
        }
    }

    private fun getMimeType(fileName: String): String {
        return when(fileName.substringAfterLast(".").lowercase()) {
            "pdf" -> "application/pdf"
            "doc", "docx" -> "application/msword"
            "xls", "xlsx" -> "application/vnd.ms-excel"
            "jpg", "jpeg" -> "image/jpeg"
            "png" -> "image/png"
            "txt" -> "text/plain"
            else -> "*/*"
        }
    }

    private fun checkStoragePermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            Environment.isExternalStorageManager()
        } else {
            checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
        }
    }

    private suspend fun updateStatus(message: String) {
        withContext(Dispatchers.Main) {
            statusText.text = message
            Toast.makeText(this@MainActivity, message, Toast.LENGTH_SHORT).show()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        sftpClient.disconnect()
    }
} 